package com.ld.admin.shiro.filter;

import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;

import com.ld.admin.shiro.ShiroUtils;
import com.ld.admin.util.PermissionUtil;
import com.ld.shieldsb.common.web.util.Web;
import com.ld.shieldsb.common.web.util.WebUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 自定义角色权限过滤器
 * 
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2020年9月16日 上午10:56:23
 *
 */
@Slf4j
public class MyRolesAuthorizationFilter extends AuthorizationFilter {

    // 重写了允许访问的方法
    @Override
    protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception {
        if (!PermissionUtil.checkPermission(WebUtils.toHttp(req))) { // 不需要检查权限直接返回true
            return true;
        }
        // Subject subject = getSubject(req, resp);
        String[] rolesArray = (String[]) mappedValue;
        // 没有角色限制，有权限访问
        if (rolesArray == null || rolesArray.length == 0) {
            return true;
        }
        Set<String> roleNames = PermissionUtil.getUserPermSubjects(WebUtils.toHttp(req));
        for (int i = 0; i < rolesArray.length; i++) {
            // 若当前用户是rolesArray中的任何一个，则有权限访问
            if (roleNames.contains(rolesArray[i])) {
                return true;
            }
        }
        return false;
    }

    // 重写了无访问权限的处理
    @Override
    protected boolean onAccessDenied(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception {
        HttpServletRequest request = (HttpServletRequest) req;
        String uri = Web.Request.getRelativeURI(request); // 相对uri
        log.warn("角色拦截的url:  " + uri + " ip:" + WebUtil.getIpAddr(request));

        // 检查是否拥有访问权限
        Subject subject = this.getSubject(request, resp);
        if (subject.getPrincipal() == null) {
            this.saveRequestAndRedirectToLogin(request, resp); // 未登录跳转到登录页
        } else {
            // 转换成http的请求和响应
            HttpServletResponse response = (HttpServletResponse) resp;

            // 获取请求头的值
            String header = request.getHeader("X-Requested-With");
            // ajax 的请求头里有X-Requested-With: XMLHttpRequest 正常请求没有
            if ("XMLHttpRequest".equalsIgnoreCase(header)) {
                ShiroUtils.sendJsonErrMsg(response, "没有权限操作！");
            } else { // 正常请求
                String unauthorizedUrl = this.getUnauthorizedUrl();
                if (StringUtils.hasText(unauthorizedUrl)) {
                    WebUtils.issueRedirect(request, response, unauthorizedUrl);
                } else {
                    WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
                }
            }

        }
        return false;
    }

}
